package com.coreJava.test01;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * 作者: LCG
 * 日期: 2019/9/1 16:43
 * 描述:
 */
@RestController
public class TestController {

    @RequestMapping("test01")
    public String test01(){

        long start1 = System.currentTimeMillis();

        CompletableFuture<String> future =CompletableFuture.supplyAsync(()->Test0101.get(10,"A"));

        Random random = new Random();

        for(int i=10;i>0;i--){
            int yy=random.nextInt(100);
            int xx=random.nextInt(100);
            int i1 = random.nextInt(10);
            System.out.println("-------->"+i1);
            CompletableFuture<String> stringCompletableFuture = future.thenCombineAsync(
                    CompletableFuture.supplyAsync(() -> Test0101.get(i1, Integer.toString(xx + yy))),
                    (x, y) -> x + y);
            future=stringCompletableFuture;
        }

        future.thenAccept((s)->{
            System.out.println("--------数据的执行结果------"+s);
        });

        long end = System.currentTimeMillis();

        System.out.println(end-start1);

        return "test01";
    }


    /**
     * 手动的完成一个任务
     * @return
     */
    @RequestMapping("test02")
    public String test02(){

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> Test0101.get(10, "A"));
        future.thenAccept((s)->{
            System.out.println("-------->"+s);
        });
        //future.complete("完成");//这个complate方法用于手动完成一个任务，这时候如果任务还没有完成的话就不会有返回结果

        System.out.println("==========");
        future.thenAccept((s)-> System.out.println(s));
        return "ok";
    }

    /**
     * 当所有的任务都完成的时候
     * @return
     */
    @RequestMapping("test03")
    public String test03() throws ExecutionException, InterruptedException {

        CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(
                CompletableFuture.supplyAsync(() -> Test0101.get(10, "Y1")),
                CompletableFuture.supplyAsync(() -> Test0101.get(15, "Y2")),
                CompletableFuture.supplyAsync(() -> Test0101.get(7, "Y3")),
                CompletableFuture.supplyAsync(() -> Test0101.get(9, "Y4"))
        );

        Object o = objectCompletableFuture.get();
        objectCompletableFuture.thenAccept((s)->{
            System.out.println("======>"+s);
        });
        return o.toString();
    }

    /**
     * 当所有的任务都完成的时候,
     * @return
     */
    @RequestMapping("test04")
    public String test04() throws ExecutionException, InterruptedException {

        List<CompletableFuture> list=new ArrayList<>();
        list.add(CompletableFuture.supplyAsync(() -> Test0101.get(10, "Y1")));
        list.add(CompletableFuture.supplyAsync(() -> Test0101.get(15, "Y2")));
        list.add(CompletableFuture.supplyAsync(() -> Test0101.get(7, "Y3")));
        list.add(CompletableFuture.supplyAsync(() -> Test0101.get(9, "Y1")));

        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                list.toArray(new CompletableFuture[list.size()])
        );

        CompletableFuture<List<Object>> listCompletableFuture = allFutures.thenApply(yy -> {
            return list.stream().map(tt -> tt.join()).collect(Collectors.toList());
        });

        //List<Object> objects = listCompletableFuture.get();
        listCompletableFuture.thenAccept((s)->{
            System.out.println("-----"+s);
        });
        return "";

    }

    /**
     * 测试任务的合并
     */
    @RequestMapping("test05")
    public void test05(){

        CompletableFuture.supplyAsync(()->Test0101.get(10,"AA"))
                          .thenCombine(
                                  CompletableFuture.supplyAsync(()->Test0101.get(5,"BB")),
                                  (x,y)-> new StringBuffer(x).append(y).toString()
                                  )
                          .thenAccept((result)->{
                              System.out.println("======result======>"+result);
                          });

    }

    /**
     * 当做的最快的任务返回的时候
     */
    @RequestMapping("test06")
    public void test06(){

        List<CompletableFuture> list=new ArrayList<>();
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(10,"AA")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(1,"BB")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(5,"CC")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(6,"DD")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(8,"EE")));

        CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(list.toArray(new CompletableFuture[list.size()]));

        objectCompletableFuture.thenAccept((result)->{
            System.out.println("===========>"+result);
        });

    }


    /**
     * 当所有的任务都完成的时候
     */
    @RequestMapping("test07")
    public void allTaskOver(){

        List<CompletableFuture> list=new ArrayList<>();
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(10,"AA")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(1,"BB")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(5,"CC")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(6,"DD")));
        list.add(CompletableFuture.supplyAsync(()->Test0101.get(8,"EE")));

        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(list.toArray(new CompletableFuture[list.size()]));

        //整理每一个任务运行后的数据
        CompletableFuture<List<Object>> listCompletableFuture = voidCompletableFuture.thenApply((yy) -> {
            return list.stream().map(CompletableFuture::join).collect(Collectors.toList());
        });

        //如果任务有异常的处理
        CompletableFuture<List<Object>> exceptionally = listCompletableFuture.exceptionally((ex) -> {
            return Collections.singletonList(ex.getMessage());
        });

        ReentrantLock reentrantLock=new ReentrantLock();

        reentrantLock.lock();

        listCompletableFuture.thenAccept((result)->{
            System.out.println(exceptionally+"===========>"+result);
        });

        reentrantLock.unlock();

        //ArrayBlockingQueue



    }


}
